#include <ncurses.h>
#include <stdio.h>
#include <gmp.h>
#include <string.h>
#include "curses.h"

void init();
void end();
void message(char *str);



void init()
{
  initscr();
  start_color();
  init_pair(1, COLOR_WHITE, COLOR_RED);
}

void end()
{
  endwin();
}

/* Clear the screen and display <str> in the center. */
void guimessage(char *str)
{
  int x, y;
  int len;

  /* Calculate y and x so they're centered */
  getmaxyx(stdscr, y,x);
  y /= 2;

  len = strlen(str);
  x = x/2 - len/2;

  clear();
  mvaddstr(y,x, str);
  move(0,0);
  refresh();
  getch();
}

/* Stage 3: show the binary search */
void stage3_display(bool initial, bool final, mpz_t min, mpz_t max)
{
  int x, y, maxlen;
  int sx, sy, ex, ey;
  static mpz_t MIN, MAX, TOT;
  mpz_t gmin, gmax;

  if (initial)
  {
    mpz_init_set(MIN, min);
    mpz_init_set(MAX, max);
    mpz_init(TOT);
    mpz_sub(TOT, MAX, MIN);
  }

  if (final)
  {
    mpz_clear(MIN);
    mpz_clear(MAX);

    return;
  }

  mpz_init(gmin);
  mpz_init(gmax);

  /* Get window size */
  getmaxyx(stdscr, y, x);
  maxlen = y * x;

  /* Find the start and end points */
  mpz_sub(gmin, min, MIN);
  mpz_mul_ui(gmin, gmin, 100000);
  mpz_fdiv_q(gmin, gmin, TOT);
  sx = (mpz_get_ui(gmin) * maxlen)/100000;
  sy = sx / x;
  sx = sx % x;

  mpz_sub(gmax, max, MIN);
  mpz_mul_ui(gmax, gmax, 100000);
  mpz_cdiv_q(gmax, gmax, TOT);
  ex = (mpz_get_ui(gmax) * maxlen)/100000;
  ey = ex / x;
  ex = ex % x;

  mpz_clear(gmin);
  mpz_clear(gmax);

  /* If it's too small to see... zoom in */
  if (sx == ex && sy == ey && !initial)
  {  
    mpz_set(MIN, min);
    mpz_set(MAX, max);
    mpz_sub(TOT, MAX, MIN);
  }
  else
  {
    /* Draw between them to show the search space */
    clear();
    refresh();
    attrset(COLOR_PAIR(1));
    while(sy < ey || sx < ex)
    {
      mvinsch(sy, sx, '@');
      if (++sx >= x)
      { 
        sx = 0; 
        sy += 1;
      }
      else
      {
        sx += 1;
      }
    }
    refresh();
    attrset(COLOR_PAIR(0));
  }

  return;
}


